use std::collections::HashMap;
use crate::service::model::chat_model::{MessageList, Message};
use std::fmt::Error;
use std::borrow::{Borrow, BorrowMut};
use std::sync::Arc;
use crate::common::utils::parse_utils::{parse_i32, parse_usize};
use crate::sql::chat::{get_user_info, get_message_num, get_message_list_item_sql};
use sqlx::{Pool, Postgres};

pub struct ChatRedis {
    pub message_list: HashMap<usize, HashMap<usize, MessageList>>,
    pub message: HashMap<usize, Vec<Message>>,
}

impl ChatRedis {
    pub fn get_message(&mut self, key: usize) -> &Vec<Message> {
        if !self.message.contains_key(&key) {
            let vec = Vec::new();
            self.message.insert(key, vec);
        }
        return self.message.get(&key).unwrap();
    }

    pub fn get_message_receive(&mut self, key: usize) -> Vec<Message> {
        let mut vec: Vec<Message> = Vec::new();
        let kk = parse_i32(key.to_string()).unwrap();
        for k in self.message.keys() {
            // if k==key { continue;}
            for mut x in self.message.get(k).unwrap() {
                if x.receive_id == kk {
                    let new_message = Message {
                        id: x.id,
                        user_id: x.user_id,
                        value: x.value.clone(),
                        mold: x.mold,
                        is_read: x.is_read,
                        receive_id: x.receive_id,
                        create_time: x.create_time.clone(),
                    };
                    vec.push(new_message);
                }
            }
        }


        return vec;
    }


    pub fn add_message(&mut self, message: Message) {
        let key = message.user_id as usize;
        if !self.message.contains_key(&key) {
            let mut vec = Vec::new();
            vec.push(message);
            self.message.insert(key, vec);
        } else {
            let mut vec = self.message.remove(&key).unwrap();
            vec.push(message);
            self.message.insert(key, vec);
        }

    }

    pub fn get_message_list(&mut self, key: usize) -> HashMap<usize, MessageList> {
        if !self.message_list.contains_key(&key) {
            let mut map = HashMap::new();
            return map;
        }
        return self.message_list.remove(&key).unwrap();
    }

    //根据receive_查找
    pub fn get_message_list_receive(&mut self, id: usize) -> HashMap<usize, MessageList> {
        let key=id;
        let mut map = HashMap::new();
        for x in self.message_list.keys() {
            let result_map = self.message_list.get(x).unwrap();
            if result_map.contains_key(&key) {
                let result = result_map.get(&key).unwrap();
                let new_result = MessageList {
                    id:result.send_id,
                    send_id: result.send_id,
                    receive_id: result.receive_id,
                    num: result.num,
                    last_message: result.last_message.clone(),
                    last_time: result.last_time.clone(),
                    send_nick: result.receive_nick.clone(),
                    send_logo: result.receive_logo.clone(),
                    receive_nick: result.send_nick.clone(),
                    receive_logo: result.send_logo.clone()
                };
                map.insert(new_result.send_id as usize, new_result);
            }
        }

        map
    }

    pub async fn  add_message_list(&mut self,pool:&Pool<Postgres>, is_this:u8,mut message_list: MessageList) {
        let key = parse_usize(&message_list.send_id.to_string()).unwrap();

        //判断是否已经有缓存user_id
        if !self.message_list.contains_key(&key) {


                //同步数据库nick，logo,num
                if let Ok(send_user)=get_user_info(pool,message_list.send_id).await {

                    message_list.send_nick=send_user.nick;
                    message_list.send_logo=send_user.logo;
                }

                if is_this!=1{
                    if let Ok(num_result)=get_message_num(pool,message_list.send_id,message_list.receive_id).await{
                        message_list.num=num_result+1;
                    }
                }


                if let Ok(receive_user)=get_user_info(pool,message_list.receive_id).await{
                    message_list.receive_nick=receive_user.nick;
                    message_list.receive_logo=receive_user.logo;
                }

                //插入缓存
                let mut map = HashMap::new();
                map.insert(message_list.receive_id as usize, message_list);
                self.message_list.insert(key, map);


        } else {
            let mut map = self.message_list.remove(&key).unwrap();
            let receive_key=message_list.receive_id as usize;
            //判断是否有缓存receive_id
            if map.contains_key(&receive_key) {
                let mut value = map.remove(&receive_key).unwrap();
                if is_this!=1{
                    message_list.num = value.num + 1;
                }else{
                    message_list.num=0;
                }
                message_list.send_logo=value.send_logo;
                message_list.send_nick=value.send_nick;
                message_list.receive_logo=value.receive_logo;
                message_list.receive_nick=value.receive_nick;
                map.insert(message_list.receive_id as usize, message_list);
            } else {
                //同步数据库nick，logo,num
                if let Ok(send_user)=get_user_info(pool,message_list.send_id).await {
                    message_list.send_nick=send_user.nick;
                    message_list.send_logo=send_user.logo;
                }

                if is_this!=1{
                    if let Ok(num_result)=get_message_num(pool,message_list.send_id,message_list.receive_id).await{
                        message_list.num=num_result;
                    }
                }

                if let Ok(receive_user)=get_user_info(pool,message_list.receive_id).await{
                    message_list.receive_nick=receive_user.nick;
                    message_list.receive_logo=receive_user.logo;
                }
                map.insert(message_list.receive_id as usize, message_list);
            }
            self.message_list.insert(key, map);
        }
    }

    pub async fn message_list_read(&mut self, pool:&Pool<Postgres>, send_id:usize, receive_id:usize){

        if !self.message_list.contains_key(&send_id) {
            if let Ok(mut message_list)=get_message_list_item_sql(pool, send_id.clone(), receive_id.clone()).await {
                let mut map=HashMap::new();
                message_list.num=0;
                map.insert(receive_id,message_list);
                self.message_list.insert(send_id,map);
            }
        }else{
            let mut map = self.message_list.remove(&send_id).unwrap();
            if map.contains_key(&receive_id) {
                let mut message_list=map.remove(&receive_id).unwrap();
                message_list.num=0;
                map.insert(receive_id,message_list);
            }else{
                if let Ok(mut message_list)=get_message_list_item_sql(pool, send_id.clone(), receive_id.clone()).await {
                    message_list.num=0;
                    map.insert(receive_id,message_list);
                }
            }
            self.message_list.insert(send_id,map);
        }

    }
}